/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS  
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). 
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.  
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR  
 * COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND  
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE  
 * MAY BE CONSIDERED TO BE A CONTRACT,
 * THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED 
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 * 
 */
package com.lineage.server.model.skill;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.lineage.console.DataError;
import com.lineage.server.datatables.SkillsTable;
import com.lineage.server.model.L1Character;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.packetserver.S_OwnCharStatus;
import com.lineage.server.packetserver.S_ServerMessage;
import com.lineage.server.templates.L1Skills;

/**
 * Class <code>L1SkillClass</code> 技能模组.
 * 
 * @author jrwz
 * @version 2012-7-24上午11:13:22
 * @see com.lineage.server.model.skill
 * @since JDK1.7
 */
public final class L1SkillClass {
    /** 提示信息. */
    private static final Log LOG = LogFactory.getLog(L1SkillClass.class);

    /** SkillID执行类位置. */
    private static final Map<Integer, L1SkillExecutor> _classList = new HashMap<Integer, L1SkillExecutor>();

    /** 实例. */
    private static L1SkillClass instance;

    /**
     * 当实例为空时才新建一个.
     * 
     * @return 实例
     */
    public static L1SkillClass getInstance() {
        if (instance == null) {
            instance = new L1SkillClass();
        }
        return instance;
    }

    /**
     * 发送技能停止信息.
     * 
     * @param charaPc
     *            - 角色
     * @param skillid
     *            - 技能ID
     */
    private static void skillStopMessage(final L1PcInstance charaPc,
            final int skillid) {
        final L1Skills l1skills = SkillsTable.getInstance()
                .getTemplate(skillid);
        // 无该技能、空角色
        if ((l1skills == null) || (charaPc == null)) {
            return;
        }

        final int msgID = l1skills.getSysmsgIdStop(); // 取回技能停止时要发送的信息
        if (msgID > 0) {
            charaPc.sendPackets(new S_ServerMessage(msgID));
        }
    }

    /**
     * 加入Class清单.
     * 
     * @param skillId
     *            - 技能编号
     * @param className
     *            - 执行类的位置
     */
    public void addList(final int skillId, final String className) {
        // Class为0
        if (className.equals("0")) {
            return;
        }
        try {
            final StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("com.lineage.server.model.skill.executor.");
            stringBuilder.append(className);
            final Class<?> cls = Class.forName(stringBuilder.toString());
            final L1SkillExecutor exe = (L1SkillExecutor) cls.getMethod("get")
                    .invoke(null);
            _classList.put(Integer.valueOf(skillId), exe);
        } catch (final ClassNotFoundException e) {
            final String error = "技能Class档案 (" + className + ") 错误 (SkillId:"
                    + skillId + ")";
            LOG.error(error);
            DataError.isError(LOG, error, e);
        } catch (final IllegalArgumentException e) {
            LOG.error(e.getLocalizedMessage(), e);
        } catch (final IllegalAccessException e) {
            LOG.error(e.getLocalizedMessage(), e);
        } catch (final InvocationTargetException e) {
            LOG.error(e.getLocalizedMessage(), e);
        } catch (final SecurityException e) {
            LOG.error(e.getLocalizedMessage(), e);
        } catch (final NoSuchMethodException e) {
            LOG.error(e.getLocalizedMessage(), e);
        }
    }

    /**
     * 技能执行.
     * 
     * @param user
     *            - 使用对象
     * @param cha
     *            - 对象
     * @param target
     *            - 目标
     * @param targetID
     *            - 目标编号
     * @param skillId
     *            - 技能编号
     * @param getBuffIconDuration
     *            - BUFF图标持续时间
     */
    public void execute(final L1Character user, final L1Character cha,
            final L1Character target, final int targetID, final int skillId,
            final int getBuffIconDuration) {
        try {
            // 取得Class执行位置
            final L1SkillExecutor exe = _classList
                    .get(Integer.valueOf(skillId));
            if (exe != null) {
                exe.execute(user, cha, target, targetID, skillId,
                        getBuffIconDuration);
            }
        } catch (final Exception e) {
            LOG.error(e.getLocalizedMessage(), e);
        }
    }

    /**
     * 技能停止.
     * 
     * @param cha
     *            - 对象
     * @param skillId
     *            - 技能编号
     */
    public void stop(final L1Character cha, final int skillId) {
        try {
            // 取得Class执行位置
            final L1SkillExecutor exe = _classList
                    .get(Integer.valueOf(skillId));
            if (exe != null) {
                exe.stop(cha, skillId);
                if (cha instanceof L1PcInstance) {
                    final L1PcInstance pc = (L1PcInstance) cha;
                    skillStopMessage(pc, skillId);
                    pc.sendPackets(new S_OwnCharStatus(pc)); // 更新角色属性与能力值
                }
            } else {
                L1SkillStop.execute(cha, skillId);
            }
        } catch (final Exception e) {
            LOG.error(e.getLocalizedMessage(), e);
        }
    }
}
